#include <reg51.h>
#include <intrins.h>
#include "config.h"   //定义用到的IO
#include "adc.h"      //adc驱动
#include "lcd1602.h"  //lcd1602 I2C 驱动
#include "nrf24l01.h" //无线模块驱动
// #include "zimo.h"
#define uchar unsigned char
#define uint unsigned int
/*******************************************************
        晶振11.0592Mhz，波特率115200
*******************************************************/
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4) // 115200波特率可更改：9600、4800等
// 串口
sfr AUXR = 0x8e; //串口寄存器
//T2作为波特率发生器
sfr T2H = 0xd6;
sfr T2L = 0xd7;
// 掉电定时唤醒
sfr WKTCL = 0xAA; //掉电唤醒定时器计时低字节
sfr WKTCH = 0xAB; //掉电唤醒定时器计时高字节
/*************************************************
        设置唤醒时间，单位：毫秒
     *  （本机）掉电唤醒定时器的频率: 35.575KHz
     * 长时间休眠只有重复进入掉电模式
     * 单次最大设置数32767，也就是32766+1，约16秒
     *  10^16*16*计数次数/Fwt   微秒 
**************************************************/
void SetWakeUp(uint SetTime)
{
    SetTime = (uint)((35575UL * (uint)SetTime) / 16000); //计算计数次数
    if (SetTime > 0)
        SetTime--;
    WKTCL = (uchar)SetTime;
    WKTCH = (uchar)(SetTime >> 8) | 0x80; //赋值WKTCH寄存器并允许内部停机唤醒定时器
}
/*******************************
        uart驱动由范例自动生成
*******************************/
bit busy;        //用于标记是否还在发送数据
char wptr;       //接收++
char rptr;       //发送++
char buffer[16]; //串口接收到的数据16个字节
/*******************************
        串口初始化
*******************************/
void Uart_Init()
{
    SCON = 0x50;
    T2L = BRT;
    T2H = BRT >> 8;
    AUXR = 0x15; //T2时，
    wptr = 0x00;
    rptr = 0x00;
    busy = 0;
    ES = 1; //串口中断
}
/*******************************
        串口发送字节
*******************************/
void UartSend(char dat)
{
    while (busy)
        ;
    busy = 1;
    SBUF = dat;
}
/*******************************
        串口发送字符串
*******************************/
void UartSendStr(char *p)
{
    while (*p)
    {
        UartSend(*p++);
    }
}

void main()
{
    uchar temp[8]; //输出到lcd的内容
    uint vol;
    // 所有IO口全部初始化为准双向口(传统IO)，由各自init()选择进一步设置IO口
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    // 初始化
    LCD_Init();
    ADC_Init();
    Uart_Init();
    Nrf24l01_Init();
    EA = 1;          //总中断打开
    SetWakeUp(5000); //设置唤醒间隔ms
    while (1)
    {
        // lcd_show_han();
        // 先执行一次
        // lcd_write_com(0x01); //清屏
        delay(500); //延时下等待启动稳定
        vol = ADC_Value();
        // vol = ADC_Aver(10);
        lcd_show_han();
        //TX_BUF nr24l01 发送数据
        TX_BUF[0] = 'B'; //用于标记起始
        TX_BUF[1] = (vol + 5) / 1000;
        TX_BUF[2] = (vol + 5) % 1000 / 100;
        TX_BUF[3] = (vol + 5) % 100 / 10;
        TX_BUF[4] = '\n'; //用于标记结束
        TX_Mode(TX_BUF);  // 把nRF24L01设置为发送模式并发送数据
        Check_ACK(1);     // 等待发送完毕，清除TX FIFO
        //用于lcd1602显示
        temp[0] = vol / 1000 + 0x30;
        temp[1] = '.';
        temp[2] = vol % 1000 / 100 + 0x30;
        temp[3] = vol % 100 / 10 + 0x30;
        temp[4] = vol % 10 + 0x30;
        temp[5] = 'V';
        temp[6] = '\0';
        lcd_show_string(1, 3, temp);
        //用于串口发送
        UartSend(temp[0]);
        UartSend(temp[2]);
        UartSend(temp[3]);
        UartSend(temp[4]);
        while (busy) //等待发送完成
            ;
        PCON = 0x02; //进入掉电模式
        _nop_();
        _nop_();
        //唤醒后从这里执行
    }
}
void UartIsr() interrupt 4 //串口中断4
{
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
    if (RI)
    {
        RI = 0;
        buffer[wptr++] = SBUF;
        wptr &= 0x0f;
    }
}